#region Namespaces

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

using Vibstudio.X4NET.IO.INI;
using Vibstudio.X4NET.IO.INI.Model;
using Vibstudio.X4NET.IO.Path;

#endregion

namespace Vibstudio.X4NET.Globalization
{
    public class INILabelingProvider : LabelingProviderBase, ILabelingProvider
    {
        private const string DEFAULT_LANG_FILE_NAME = "lang.cfg";

        private IniData _ini;

        public INILabelingProvider()
            : this(string.Empty)
        {
        }

        protected INILabelingProvider(string lang = "", string langFileName = "", string appLangKey = "")
        {
            AppLang = lang;
            AppLangFileName = string.IsNullOrEmpty(langFileName) ? DEFAULT_LANG_FILE_NAME : langFileName;
            AppLangKey = string.IsNullOrEmpty(appLangKey) ? DefaultAppLangKey : appLangKey;
        }
        
        public IList<DictionaryEntry> LabelDictionary(string lang)
        {
            IList<DictionaryEntry> labelDictionary = new List<DictionaryEntry>();

            try
            {
                if (!string.IsNullOrEmpty(lang))
                {
                    KeyDataCollection labelCollection = Ini.Sections.GetSectionData(lang).Keys;
                    foreach (KeyData keyData in labelCollection)
                    {
                        labelDictionary.Add(new DictionaryEntry(keyData.KeyName, keyData.Value));
                    }
                }
                else
                {
                    foreach (SectionData data in Ini.Sections)
                    {
                        foreach (KeyData keyData in data.Keys)
                        {
                            labelDictionary.Add(new DictionaryEntry(keyData.KeyName, keyData.Value));
                        }
                    }
                }

            }
            catch (Exception exception)
            {
                Trace.WriteLine(string.Format("Exception: {0}", exception), "INILabelingProvider.LabelDictionary");
            }

            return labelDictionary;
        }

        public virtual string this[string name, string lang = ""]
        {
            get
            {
                lang = string.IsNullOrEmpty(lang) ? AppLang : lang;

                try
                {
                    return string.IsNullOrEmpty(lang) ? string.Empty : Ini.Sections.GetSectionData(lang).Keys.GetKeyData(name).Value;
                }
                catch (Exception exception)
                {
                    Trace.WriteLine(string.Format("Exception: {0}", exception), "INILabelingProvider.GetLabel");
                    return string.Empty;
                }
            }
        }

        protected IniData Ini
        {
            get
            {
                try
                {
                    FilePath filePath = FilePath.Create(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppLangFileName));
                    if (!filePath.Exists)
                    {
                        filePath = FilePath.Create(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", AppLangFileName));
                    }

                    _ini = new FileIniDataParser().ReadFile(filePath.Path);
                }
                catch (Exception exception)
                {
                    Trace.WriteLine(string.Format("Exception: {0}", exception), "INILabelingProvider.ctor");
                    _ini = null;
                }

                return _ini;
            }
        }
    }
}